package com.one.react.internal;

import com.sun.source.tree.MethodTree;
import com.sun.source.tree.Tree;
import com.sun.source.util.TreeScanner;
import com.sun.tools.javac.parser.JavacParser;
import com.sun.tools.javac.tree.JCTree;
import com.sun.tools.javac.tree.TreeTranslator;
import com.sun.tools.javac.util.Context;

import java.util.List;

import javax.lang.model.element.Name;

public class FieldAssignTranslator extends TreeScanner<Tree, Void> {
    private Context context;
    private List<JCTree.JCVariableDecl> observableVars;

    public FieldAssignTranslator(Context context, List<JCTree.JCVariableDecl> observableVars) {
        this.context = context;
        this.observableVars = observableVars;
    }

    @Override
    public Tree visitMethod(MethodTree node, Void unused) {
        JCTree.JCMethodDecl tree = (JCTree.JCMethodDecl) node;
        TreeTranslator translator = new MyTranslator();
        return translator.translate(tree);
    }

    private class MyTranslator extends TreeTranslator {
        @Override
        public void visitAssign(JCTree.JCAssign tree) {
            JCTree.JCExpression variable = tree.getVariable();
            if (!(variable instanceof JCTree.JCIdent)) {
                result = tree;
                return;
            }
            JCTree.JCIdent ident = (JCTree.JCIdent) variable;
            if (!isStateVar(ident.name)) {
                result = tree;
                return;
            }
            String code = ident.name + ".update(" + tree.getExpression() + ");";
            result = MyParser.getInstance(context)
                    .getParserFor(code)
                    .parseExpression();
        }
    }

    private boolean isStateVar(Name name) {
        for (JCTree.JCVariableDecl observableVar : observableVars) {
            if (observableVar.name == name) {
                return true;
            }
        }
        return false;
    }
}
